<?php
/* $Id$ */
/*
	snort.inc
	Copyright (C) 2006 Scott Ullrich
	part of pfSense
	All rights reserved.

	Redistribution and use in source and binary forms, with or without
	modification, are permitted provided that the following conditions are met:

	1. Redistributions of source code must retain the above copyright notice,
	   this list of conditions and the following disclaimer.

	2. Redistributions in binary form must reproduce the above copyright
	   notice, this list of conditions and the following disclaimer in the
	   documentation and/or other materials provided with the distribution.

	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
	POSSIBILITY OF SUCH DAMAGE.
*/
require_once("pfsense-utils.inc");

/* Allow additional execution time 0 = no limit. */
ini_set('max_execution_time', '9999');
ini_set('max_input_time', '9999');

/* define oinkid */
if($config['installedpackages']['snort'])
	$oinkid = $config['installedpackages']['snort']['config'][0]['oinkmastercode'];

function sync_package_snort_reinstall() 
{
	global $config;
	if(!$config['installedpackages']['snort'])
		return;
    
	/* create snort configuration file */
	create_snort_conf();
  
	/* start snort service */
	start_service("snort");
}

function sync_package_snort()
{
	global $config, $g;

	if($g['platform'] != 'stairway' || $config['installedpackages']['snort']['config'][0]['enable'] != 'on')
	{
	    if(is_process_running("snort"))
	       killbyname("snort");
        if(is_process_running("snort2c"))
           killbyname("snort2c");
        snort_install_cron(false);
	    return;
	}
	
	if($g['booting'])
	   echo 'Starting Snort...';
	
	mwexec("mkdir -p /var/log/snort/");

	if(!file_exists("/var/log/snort/alert"))
		touch("/var/log/snort/alert");

	/* snort -> advanced features */
	$bpfbufsize = $config['installedpackages']['snortadvanced']['config'][0]['bpfbufsize'];
	$bpfmaxbufsize = $config['installedpackages']['snortadvanced']['config'][0]['bpfmaxbufsize'];
	$bpfmaxinsns = $config['installedpackages']['snortadvanced']['config'][0]['bpfmaxinsns'];

	/* set the snort performance model */
	if($config['installedpackages']['snort']['config'][0]['performance'])
		$snort_performance = $config['installedpackages']['snort']['config'][0]['performance'];
	else
		$snort_performance = "ac-bnfa";

	conf_mount_rw();
	/* create a few directories and ensure the sample files are in place */
	exec("/bin/mkdir -p /usr/local/etc/snort");
	exec("/bin/mkdir -p /var/log/snort");
	exec("/bin/mkdir -p /usr/local/etc/snort/rules");
	exec("/bin/cp -n /usr/local/etc/snort/unicode.map-sample /usr/local/etc/snort/unicode.map > /dev/null 2>&1");
	exec("/bin/cp -n /usr/local/etc/snort/classification.config-sample /usr/local/etc/snort/classification.config > /dev/null 2>&1");
	exec("/bin/cp -n /usr/local/etc/snort/gen-msg.map-sample /usr/local/etc/snort/gen-msg.map > /dev/null 2>&1");
	exec("/bin/cp -n /usr/local/etc/snort/generators-sample /usr/local/etc/snort/generators > /dev/null 2>&1");
	exec("/bin/cp -n /usr/local/etc/snort/reference.config-sample /usr/local/etc/snort/reference.config > /dev/null 2>&1");
	exec("/bin/cp -n /usr/local/etc/snort/sid-msg.map-sample /usr/local/etc/snort/sid-msg.map > /dev/null 2>&1");
	exec("/bin/cp -n /usr/local/etc/snort/sid-sample /usr/local/etc/snort/sid > /dev/null 2>&1");
	exec("/bin/cp -n /usr/local/etc/snort/threshold.conf-sample /usr/local/etc/snort/threshold.conf > /dev/null 2>&1");
	exec("/bin/cp -n /usr/local/etc/snort/unicode.map-sample /usr/local/etc/snort/unicode.map > /dev/null 2>&1");
	exec("/bin/rm -f /usr/local/etc/rc.d/snort > /dev/null 2>&1");

	$first = 0;
	$snortInterfaces = array(); /* -gtm  */
	
	$if_list = $config['installedpackages']['snort']['config'][0]['iface_array'];
	$if_array = split(',', $if_list);
	//print_r($if_array);
	if($if_array) {
		foreach($if_array as $iface) {
			$if = convert_friendly_interface_to_real_interface_name($iface);
			
			/* build a list of user specified interfaces -gtm */      
			if($if){      
			  array_push($snortInterfaces, $if);
			  $first = 1;
			}
		}	
	    
		if (count($snortInterfaces) < 1) {
			log_error("Snort will not start.  You must select an interface for it to listen on.");
			snort_install_cron(false);
			return;
		}
	}
	//print_r($snortInterfaces);
	
	/* create log directory */
	$start  = "/bin/mkdir -p /var/log/snort";

	/* snort advanced features - bpf tuning */
	if($bpfbufsize)
		$start .= ";sysctl net.bpf.bufsize={$bpfbufsize}";
	if($bpfmaxbufsize)
		$start .= ";sysctl net.bpf.maxbufsize={$bpfmaxbufsize}";
	if($bpfmaxinsns)
		$start .= ";sysctl net.bpf.maxinsns={$bpfmaxinsns}";

	/* go ahead and issue bpf changes */
	if($bpfbufsize)
		mwexec_bg("sysctl net.bpf.bufsize={$bpfbufsize}");
	if($bpfmaxbufsize)
		mwexec_bg("sysctl net.bpf.maxbufsize={$bpfmaxbufsize}");
	if($bpfmaxinsns)
		mwexec_bg("sysctl net.bpf.maxinsns={$bpfmaxinsns}");

	/* always stop snort2c before starting snort -gtm */
  $start .= ";/usr/bin/killall snort2c > /dev/null 2>&1";

  /* start a snort process for each interface -gtm */
  /* Note the sleep delay.  Seems to help getting mult interfaces to start -gtm */
  /* snort start options are; config file, log file, demon, interface, packet flow, alert type, quiet */
  /* TODO; get snort to start under nologin shell */
  $first = true;
  foreach($snortInterfaces as $snortIf)
  {
    if(!$first)
        $start .= ";sleep 8";
  	$start .= ";snort -c /usr/local/etc/snort/snort.conf -l /var/log/snort -D -i {$snortIf} -q";
  	$first = false;
  }    
    
	/* if block offenders is checked, start snort2c */
	if($_POST['blockoffenders'])
		$start .= "\nsleep 8;snort2c -w /var/db/whitelist -a /var/log/snort/alert";
    
	$sample_before = "\nBEFORE_MEM=`top | grep Free | grep Wired | awk '{print \$10}'`\n";
	$sample_after = "\nAFTER_MEM=`top | grep Free | grep Wired | awk '{print \$10}'`\n";
	$sleep_before_final = "\necho \"Sleeping before final memory sampling...\"\nsleep 17";
	$total_free_after = "\nTOTAL_USAGE=`top | grep snort | grep -v grep | awk '{ print \$6 }'`\n";
	$echo_usage = "\necho \"Ram free BEFORE starting Snort: \${BEFORE_MEM} -- Ram free AFTER starting Snort: \${AFTER_MEM}\" -- Mode {$snort_performance} -- Snort memory usage: \$TOTAL_USAGE | logger -p daemon.info -i -t SnortStartup\n";

	/* write out rc.d start/stop file */
	write_rcfile(array(
			"file" => "snort.sh",
			"start" => "{$sample_before}{$start}{$sleep_before_final}{$sample_after}{$echo_usage}",
			"stop" => "/usr/bin/killall snort; killall snort2c"
		)
	);

	/* create snort configuration file */
	create_snort_conf();
	snort_install_cron(true);

	/* start snort service */
	conf_mount_ro();
	start_service("snort");
    
	if($g['booting'])
       echo "done\n";
}

function create_snort_conf() {
	global $config, $g;
	/* write out snort.conf */
	$snort_conf_text = generate_snort_conf();
	conf_mount_rw();
	$conf = fopen("/usr/local/etc/snort/snort.conf", "w");
	if(!$conf) {
		log_error("Could not open /usr/local/etc/snort/snort.conf for writing.");
		exit;
	}
	fwrite($conf, $snort_conf_text);
	fclose($conf);
	conf_mount_ro();
}

function snort_deinstall() {
//	$text_ww   = "*/60\t* \t 1\t *\t *\t root\t /usr/bin/nice -n20 /usr/local/pkg/snort_check_for_rule_updates.php";
//	$filenamea = "/etc/crontab";
	/* remove auto rules update helper */
//	remove_text_from_file($filenamea, $text_ww);
	/* remove custom sysctl */
	remove_text_from_file("/etc/sysctl.conf", "sysctl net.bpf.bufsize=20480");
	/* decrease bpf buffers back to 4096, from 20480 */
	exec("/sbin/sysctl net.bpf.bufsize=4096");
	exec("/usr/bin/killall snort");
	sleep(5);
	exec("/usr/bin/killall -9 snort");
	exec("rm -f /usr/local/etc/rc.d/snort*");
	exec("rm -rf /usr/local/etc/snort*");
	exec("cd /var/db/pkg && pkg_delete `ls | grep snort`");
	exec("cd /var/db/pkg && pkg_delete `ls | grep mysql-client`");
	exec("cd /var/db/pkg && pkg_delete `ls | grep libdnet`");
	exec("/usr/bin/killall -9 snort");
	exec("/usr/bin/killall snort");
}

function generate_snort_conf() {

	global $config, $g;
	conf_mount_rw();
	/* obtain external interface */
	/* XXX: make multi wan friendly */
	$snort_ext_int = $config['installedpackages']['snort']['config'][0]['iface_array'][0];

	$snort_config_pass_thru = $config['installedpackages']['snortadvanced']['config'][0]['configpassthru'];
	
/* define snortalertlogtype */
$snortalertlogtype = $config['installedpackages']['snortadvanced']['config'][0]['snortalertlogtype'];
if ($snortalertlogtype == "full")
    $snortalertlogtype_type = "output alert_full: alert";
else
	$snortalertlogtype_type = "output alert_fast: alert"; 

/* define alertsystemlog */
$alertsystemlog_info_chk = $config['installedpackages']['snortadvanced']['config'][0]['alertsystemlog'];
if ($alertsystemlog_info_chk == on)
    $alertsystemlog_type = "output alert_syslog: log_alert";

/* define tcpdumplog */
$tcpdumplog_info_chk = $config['installedpackages']['snortadvanced']['config'][0]['tcpdumplog'];
if ($tcpdumplog_info_chk == on)
    $tcpdumplog_type = "output log_tcpdump: snorttcpd.log";

/* define snortmysqllog */
$snortmysqllog_info_chk = $config['installedpackages']['snortadvanced']['config'][0]['snortmysqllog'];

/* define snortunifiedlog */
$snortunifiedlog_info_chk = $config['installedpackages']['snortadvanced']['config'][0]['snortunifiedlog'];
if ($snortunifiedlog_info_chk == on)
    $snortunifiedlog_type = "output unified2: filename snort.u2, limit 128";

/* define servers and ports snortdefservers */

/* def DNS_SERVSERS */
$def_dns_servers_info_chk = $config['installedpackages']['snortdefservers']['config'][0]['def_dns_servers'];
if ($def_dns_servers_info_chk == "")
	$def_dns_servers_type = "\$HOME_NET";
else 
	$def_dns_servers_type = "$def_dns_servers_info_chk";

/* def DNS_PORTS */
$def_dns_ports_info_chk = $config['installedpackages']['snortdefservers']['config'][0]['def_dns_ports'];
if ($def_dns_ports_info_chk == "")
	$def_dns_ports_type = "53";
else 
	$def_dns_ports_type = "$def_dns_ports_info_chk";

/* def SMTP_SERVSERS */
$def_smtp_servers_info_chk = $config['installedpackages']['snortdefservers']['config'][0]['def_smtp_servers'];
if ($def_smtp_servers_info_chk == "")
	$def_smtp_servers_type = "\$HOME_NET";
else 
	$def_smtp_servers_type = "$def_smtp_servers_info_chk";

/* def SMTP_PORTS */
$def_smtp_ports_info_chk = $config['installedpackages']['snortdefservers']['config'][0]['def_smtp_ports'];
if ($def_smtp_ports_info_chk == "")
	$def_smtp_ports_type = "25";
else 
	$def_smtp_ports_type = "$def_smtp_ports_info_chk";

/* def MAIL_PORTS */
$def_mail_ports_info_chk = $config['installedpackages']['snortdefservers']['config'][0]['def_mail_ports'];
if ($def_mail_ports_info_chk == "")
	$def_mail_ports_type = "25,143,465,691";
else 
	$def_mail_ports_type = "$def_mail_ports_info_chk";
	
/* def HTTP_SERVSERS */
$def_http_servers_info_chk = $config['installedpackages']['snortdefservers']['config'][0]['def_http_servers'];
if ($def_http_servers_info_chk == "")
	$def_http_servers_type = "\$HOME_NET";
else 
	$def_http_servers_type = "$def_http_servers_info_chk";

/* def WWW_SERVSERS */
$def_www_servers_info_chk = $config['installedpackages']['snortdefservers']['config'][0]['def_www_servers'];
if ($def_www_servers_info_chk == "")
	$def_www_servers_type = "\$HOME_NET";
else 
	$def_www_servers_type = "$def_www_servers_info_chk";

/* def HTTP_PORTS */
$def_http_ports_info_chk = $config['installedpackages']['snortdefservers']['config'][0]['def_http_ports'];
if ($def_http_ports_info_chk == "")
	$def_http_ports_type = "80";
else 
	$def_http_ports_type = "$def_http_ports_info_chk";
	
/* def SQL_SERVSERS */
$def_sql_servers_info_chk = $config['installedpackages']['snortdefservers']['config'][0]['def_sql_servers'];
if ($def_sql_servers_info_chk == "")
	$def_sql_servers_type = "\$HOME_NET";
else 
	$def_sql_servers_type = "$def_sql_servers_info_chk";

/* def ORACLE_PORTS */
$def_oracle_ports_info_chk = $config['installedpackages']['snortdefservers']['config'][0]['def_oracle_ports'];
if ($def_oracle_ports_info_chk == "")
	$def_oracle_ports_type = "1521";
else 
	$def_oracle_ports_type = "$def_oracle_ports_info_chk";

/* def MSSQL_PORTS */
$def_mssql_ports_info_chk = $config['installedpackages']['snortdefservers']['config'][0]['def_mssql_ports'];
if ($def_mssql_ports_info_chk == "")
	$def_mssql_ports_type = "1433";
else 
	$def_mssql_ports_type = "$def_mssql_ports_info_chk";

/* def TELNET_SERVSERS */
$def_telnet_servers_info_chk = $config['installedpackages']['snortdefservers']['config'][0]['def_telnet_servers'];
if ($def_telnet_servers_info_chk == "")
	$def_telnet_servers_type = "\$HOME_NET";
else 
	$def_telnet_servers_type = "$def_telnet_servers_info_chk";
	
/* def TELNET_PORTS */
$def_telnet_ports_info_chk = $config['installedpackages']['snortdefservers']['config'][0]['def_telnet_ports'];
if ($def_telnet_ports_info_chk == "")
	$def_telnet_ports_type = "23";
else 
	$def_telnet_ports_type = "$def_telnet_ports_info_chk";
	
/* def SNMP_SERVSERS */
$def_snmp_servers_info_chk = $config['installedpackages']['snortdefservers']['config'][0]['def_snmp_servers'];
if ($def_snmp_servers_info_chk == "")
	$def_snmp_servers_type = "\$HOME_NET";
else 
	$def_snmp_servers_type = "$def_snmp_servers_info_chk";
	
/* def SNMP_PORTS */
$def_snmp_ports_info_chk = $config['installedpackages']['snortdefservers']['config'][0]['def_snmp_ports'];
if ($def_snmp_ports_info_chk == "")
	$def_snmp_ports_type = "161";
else 
	$def_snmp_ports_type = "$def_snmp_ports_info_chk";
	
/* def FTP_SERVSERS */
$def_ftp_servers_info_chk = $config['installedpackages']['snortdefservers']['config'][0]['def_ftp_servers'];
if ($def_ftp_servers_info_chk == "")
	$def_ftp_servers_type = "\$HOME_NET";
else 
	$def_ftp_servers_type = "$def_ftp_servers_info_chk";
	
/* def FTP_PORTS */
$def_ftp_ports_info_chk = $config['installedpackages']['snortdefservers']['config'][0]['def_ftp_ports'];
if ($def_ftp_ports_info_chk == "")
	$def_ftp_ports_type = "21";
else 
	$def_ftp_ports_type = "$def_ftp_ports_info_chk";
	
/* def SSH_SERVSERS */
$def_ssh_servers_info_chk = $config['installedpackages']['snortdefservers']['config'][0]['def_ssh_servers'];
if ($def_ssh_servers_info_chk == "")
	$def_ssh_servers_type = "\$HOME_NET";
else 
	$def_ssh_servers_type = "$def_ssh_servers_info_chk";
	
/* if user has defined a custom ssh port, use it */
if($config['system']['ssh']['port'])
	$ssh_port = $config['system']['ssh']['port'];
else
	$ssh_port = "22";
	
/* def SSH_PORTS */
$def_ssh_ports_info_chk = $config['installedpackages']['snortdefservers']['config'][0]['def_ssh_ports'];
if ($def_ssh_ports_info_chk == "")
	$def_ssh_ports_type = "{$ssh_port}";
else 
	$def_ssh_ports_type = "$def_ssh_ports_info_chk";
	
/* def POP_SERVSERS */
$def_pop_servers_info_chk = $config['installedpackages']['snortdefservers']['config'][0]['def_pop_servers'];
if ($def_pop_servers_info_chk == "")
	$def_pop_servers_type = "\$HOME_NET";
else 
	$def_pop_servers_type = "$def_pop_servers_info_chk";
	
/* def POP2_PORTS */
$def_pop2_ports_info_chk = $config['installedpackages']['snortdefservers']['config'][0]['def_pop2_ports'];
if ($def_pop2_ports_info_chk == "")
	$def_pop2_ports_type = "109";
else 
	$def_pop2_ports_type = "$def_pop2_ports_info_chk";
	
/* def POP3_PORTS */
$def_pop3_ports_info_chk = $config['installedpackages']['snortdefservers']['config'][0]['def_pop3_ports'];
if ($def_pop3_ports_info_chk == "")
	$def_pop3_ports_type = "110";
else 
	$def_pop3_ports_type = "$def_pop3_ports_info_chk";
	
/* def IMAP_SERVSERS */
$def_imap_servers_info_chk = $config['installedpackages']['snortdefservers']['config'][0]['def_imap_servers'];
if ($def_imap_servers_info_chk == "")
	$def_imap_servers_type = "\$HOME_NET";
else 
	$def_imap_servers_type = "$def_imap_servers_info_chk";
	
/* def IMAP_PORTS */
$def_imap_ports_info_chk = $config['installedpackages']['snortdefservers']['config'][0]['def_imap_ports'];
if ($def_imap_ports_info_chk == "")
	$def_imap_ports_type = "143";
else 
	$def_imap_ports_type = "$def_imap_ports_info_chk";
	
/* def SIP_PROXY_IP */
$def_sip_proxy_ip_info_chk = $config['installedpackages']['snortdefservers']['config'][0]['def_sip_proxy_ip'];
if ($def_sip_proxy_ip_info_chk == "")
	$def_sip_proxy_ip_type = "\$HOME_NET";
else 
	$def_sip_proxy_ip_type = "$def_sip_proxy_ip_info_chk";
	
/* def SIP_PROXY_PORTS */
$def_sip_proxy_ports_info_chk = $config['installedpackages']['snortdefservers']['config'][0]['def_sip_proxy_ports'];
if ($def_sip_proxy_ports_info_chk == "")
	$def_sip_proxy_ports_type = "5060:5090,16384:32768";
else 
	$def_sip_proxy_ports_type = "$def_sip_proxy_ports_info_chk";
	
/* def AUTH_PORTS */
$def_auth_ports_info_chk = $config['installedpackages']['snortdefservers']['config'][0]['def_auth_ports'];
if ($def_auth_ports_info_chk == "")
	$def_auth_ports_type = "113";
else 
	$def_auth_ports_type = "$def_auth_ports_info_chk";
	
/* def FINGER_PORTS */
$def_finger_ports_info_chk = $config['installedpackages']['snortdefservers']['config'][0]['def_finger_ports'];
if ($def_finger_ports_info_chk == "")
	$def_finger_ports_type = "79";
else 
	$def_finger_ports_type = "$def_finger_ports_info_chk";
	
/* def IRC_PORTS */
$def_irc_ports_info_chk = $config['installedpackages']['snortdefservers']['config'][0]['def_irc_ports'];
if ($def_irc_ports_info_chk == "")
	$def_irc_ports_type = "6665,6666,6667,6668,6669,7000";
else 
	$def_irc_ports_type = "$def_irc_ports_info_chk";
	
/* def NNTP_PORTS */
$def_nntp_ports_info_chk = $config['installedpackages']['snortdefservers']['config'][0]['def_nntp_ports'];
if ($def_nntp_ports_info_chk == "")
	$def_nntp_ports_type = "119";
else 
	$def_nntp_ports_type = "$def_nntp_ports_info_chk";
	
/* def RLOGIN_PORTS */
$def_rlogin_ports_info_chk = $config['installedpackages']['snortdefservers']['config'][0]['def_rlogin_ports'];
if ($def_rlogin_ports_info_chk == "")
	$def_rlogin_ports_type = "513";
else 
	$def_rlogin_ports_type = "$def_rlogin_ports_info_chk";
	
/* def RSH_PORTS */
$def_rsh_ports_info_chk = $config['installedpackages']['snortdefservers']['config'][0]['def_rsh_ports'];
if ($def_rsh_ports_info_chk == "")
	$def_rsh_ports_type = "514";
else 
	$def_rsh_ports_type = "$def_rsh_ports_info_chk";
	
/* def SSL_PORTS */
$def_ssl_ports_info_chk = $config['installedpackages']['snortdefservers']['config'][0]['def_ssl_ports'];
if ($def_ssl_ports_info_chk == "")
	$def_ssl_ports_type = "25,443,465,636,993,995";
else 
	$def_ssl_ports_type = "$def_ssl_ports_info_chk";
	
	/* add auto update scripts to /etc/crontab */
//	$text_ww   = "*/60\t* \t 1\t *\t *\t root\t /usr/bin/nice -n20 /usr/local/pkg/snort_check_for_rule_updates.php";
//	$filenamea = "/etc/crontab";
//	remove_text_from_file($filenamea, $text_ww);
//	add_text_to_file($filenamea, $text_ww);
//	exec("killall -HUP cron"); */

	/* should we install a automatic update crontab entry? */
	$automaticrulesupdate = $config['installedpackages']['snort']['config'][0]['automaticrulesupdate'];

	/* if user is on pppoe, we really want to use ng0 interface */
//	if($config['interfaces'][$snort_ext_int]['ipaddr'] == "pppoe")
//		$snort_ext_int = "ng0";

	/* set the snort performance model */
	if($config['installedpackages']['snort']['config'][0]['performance'])
		$snort_performance = $config['installedpackages']['snort']['config'][0]['performance'];
	else
		$snort_performance = "ac-bnfa";

	/* open snort2c's whitelist for writing */
	$whitelist = fopen("/var/db/whitelist", "w");
	if(!$whitelist) {
		log_error("Could not open /var/db/whitelist for writing.");
		return;
	}

	/* build an interface array list */
	$arpspoof = "";
	
	$if_array = get_all_lan_interfaces();

	foreach($if_array as $if) {
		/* calculate interface subnet information */
		$subnet = "{$if['sa']}/{$if['sn']}";
        if(is_subnet($subnet))
		    $home_net .= "$subnet ";
		
		$mac = get_interface_mac($if['if']);
		if($mac)
		    $arpspoof .= "preprocessor arpspoof_detect_host: {$if['ip']} $mac\n";
	}
	
	if(!empty($arpspoof))
	{
	    $arpspoof = "preprocessor arpspoof\n" . $arpspoof;
	}

	/* add all WAN ips to the whitelist */
	if(isset($config['multiwan']['if']))
	   $if_list = explode(',', $config['multiwan']['if']);
	else
	   $if_list = array("wan");
    if(count($if_list) == 0)
        $if_list = array("wan");
	foreach($if_list as $if)
	{
    	$ip = get_interface_ip($if);
    	if($ip) 
    		$home_net .= "{$ip} ";
        $gw = get_interface_gateway($if);
        if($gw) 
            $home_net .= "{$gw} ";        
	}
	
	/* Add DNS server for WAN interface to whitelist */
	$dns_servers = get_dns_servers();
	foreach($dns_servers as $dns) {
		if($dns) 
			$home_net .= "{$dns} ";		
	}
		
	/* Add loopback to whitelist (ftphelper) */
	$home_net .= "127.0.0.1 "; 	
	
	/* iterate all vips and add to whitelist */
	if($config['virtualip'])
		foreach($config['virtualip']['vip'] as $vip)
			if($vip['subnet']) 
				$home_net .= $vip['subnet'] . " ";

	if($config['installedpackages']['snortwhitelist'])
		foreach($config['installedpackages']['snortwhitelist']['config'] as $snort)
			if($snort['ip']) 
				$home_net .= $snort['ip'] . " ";
	

	/* write out whitelist, convert spaces to carriage returns */
	$whitelist_home_net = str_replace("  ", " ", $home_net);
	$whitelist_home_net = str_replace(" ", "\n", $home_net);

	/* make $home_net presentable to snort */
	$home_net = trim($home_net);
	$home_net = str_replace(" ", ",", $home_net);
	$home_net = "[{$home_net}]";

	/* foreach through whitelist, writing out to file */
	$whitelist_split = split("\n", $whitelist_home_net);
	foreach($whitelist_split as $wl)
		if(trim($wl))
			fwrite($whitelist, trim($wl) . "\n");

	/* should we whitelist vpns? */
	$whitelistvpns = $config['installedpackages']['snort']['config'][0]['whitelistvpns'];

	/* grab a list of vpns and whitelist if user desires */
	if($whitelistvpns) {
		$vpns_list = get_vpns_list();
		$whitelist_vpns = split(" ", $vpns_list);
		foreach($whitelist_split as $wl)
			if(trim($wl))
				fwrite($whitelist, trim($wl) . "\n");
	}

	/* close file */
	fclose($whitelist);

     /* open snort's threshold.conf for writing */
     $threshlist = fopen("/usr/local/etc/snort/threshold.conf", "w");
     if(!$threshlist) {
             log_error("Could not open /usr/local/etc/snort/threshold.conf for writing.");
             return;
    }

     /* list all entries to new lines  */
    if($config['installedpackages']['snortthreshold'])
            foreach($config['installedpackages']['snortthreshold']['config'] as $snortthreshlist)
                    if($snortthreshlist['threshrule'])
                             $snortthreshlist_r .= $snortthreshlist['threshrule'] . "\n";


     /* foreach through threshlist, writing out to file */
     $threshlist_split = split("\n", $snortthreshlist_r);
     foreach($threshlist_split as $wl)
             if(trim($wl))
                     fwrite($threshlist, trim($wl) . "\n");

     /* close snort's threshold.conf file */
     fclose($threshlist);	

	/* generate rule sections to load */
	$enabled_rulesets = $config['installedpackages']['snort']['rulesets'];
	if($enabled_rulesets) {
		$selected_rules_sections = "";
		$enabled_rulesets_array = split("\|\|", $enabled_rulesets);
		foreach($enabled_rulesets_array as $enabled_item)
			$selected_rules_sections  .= "include \$RULE_PATH/{$enabled_item}\n";
	}

	conf_mount_ro();

	/* build snort configuration file */
        /* TODO; feed back from pfsense users to reduce false positives */
	$snort_conf_text = <<<EOD

# snort configuration file
# generated by the pfSense
# package manager system
# see /usr/local/pkg/snort.inc
# for more information

#########################
                        #
# Define Local Network  #
                        #
#########################

var HOME_NET {$home_net}
var EXTERNAL_NET !\$HOME_NET

###################
                  #
# Define Servers  #
                  #
###################

var DNS_SERVERS [{$def_dns_servers_type}]
var SMTP_SERVERS [{$def_smtp_servers_type}]
var HTTP_SERVERS [{$def_http_servers_type}]
var SQL_SERVERS [{$def_sql_servers_type}]
var TELNET_SERVERS [{$def_telnet_servers_type}]
var SNMP_SERVERS [{$def_snmp_servers_type}]
var FTP_SERVERS [{$def_ftp_servers_type}]
var SSH_SERVERS [{$def_ssh_servers_type}]
var POP_SERVERS [{$def_pop_servers_type}]
var IMAP_SERVERS [{$def_imap_servers_type}]
var RPC_SERVERS \$HOME_NET
var WWW_SERVERS [{$def_www_servers_type}]
var SIP_PROXY_IP [{$def_sip_proxy_ip_type}]
var AIM_SERVERS \
[64.12.24.0/23,64.12.28.0/23,64.12.161.0/24,64.12.163.0/24,64.12.200.0/24,205.188.3.0/24,205.188.5.0/24,205.188.7.0/24,205.188.9.0/24,205.188.153.0/24,205.188.179.0/24,205.188.248.0/24]

########################
                       #
# Define Server Ports  #
                       #
########################

portvar HTTP_PORTS [{$def_http_ports_type}]
portvar SHELLCODE_PORTS !80
portvar ORACLE_PORTS [{$def_oracle_ports_type}]
portvar AUTH_PORTS [{$def_auth_ports_type}]
portvar DNS_PORTS [{$def_dns_ports_type}]
portvar FINGER_PORTS [{$def_finger_ports_type}]
portvar FTP_PORTS [{$def_ftp_ports_type}]
portvar IMAP_PORTS [{$def_imap_ports_type}]
portvar IRC_PORTS [{$def_irc_ports_type}]
portvar MSSQL_PORTS [{$def_mssql_ports_type}]
portvar NNTP_PORTS [{$def_nntp_ports_type}]
portvar POP2_PORTS [{$def_pop2_ports_type}]
portvar POP3_PORTS [{$def_pop3_ports_type}]
portvar SUNRPC_PORTS [111,32770,32771,32772,32773,32774,32775,32776,32777,32778,32779]
portvar RLOGIN_PORTS [{$def_rlogin_ports_type}]
portvar RSH_PORTS [{$def_rsh_ports_type}]
portvar SMB_PORTS [139,445]
portvar SMTP_PORTS [{$def_smtp_ports_type}]
portvar SNMP_PORTS [{$def_snmp_ports_type}]
portvar SSH_PORTS [{$def_ssh_ports_type}]
portvar TELNET_PORTS [{$def_telnet_ports_type}]
portvar MAIL_PORTS [{$def_mail_ports_type}]
portvar SSL_PORTS [{$def_ssl_ports_type}]
portvar SIP_PROXY_PORTS [{$def_sip_proxy_ports_type}]

# DCERPC NCACN-IP-TCP
portvar DCERPC_NCACN_IP_TCP [139,445]
portvar DCERPC_NCADG_IP_UDP [138,1024:]
portvar DCERPC_NCACN_IP_LONG [135,139,445,593,1024:]
portvar DCERPC_NCACN_UDP_LONG [135,1024:]
portvar DCERPC_NCACN_UDP_SHORT [135,593,1024:]
portvar DCERPC_NCACN_TCP [2103,2105,2107]
portvar DCERPC_BRIGHTSTORE [6503,6504]

#####################
                    #
# Define Rule Paths #
                    #
#####################

var RULE_PATH /usr/local/etc/snort/rules
# var PREPROC_RULE_PATH ./preproc_rules

################################
                               #
# Configure the snort decoder  #
                               #
################################

config checksum_mode: all
config disable_decode_alerts
config disable_tcpopt_experimental_alerts
config disable_tcpopt_obsolete_alerts
config disable_ttcp_alerts
config disable_tcpopt_alerts
config disable_ipopt_alerts
config disable_decode_drops

###################################
                                  #
# Configure the detection engine  #
# Use lower memory models         #
                                  #
###################################

config detection: search-method {$snort_performance}
config detection: max_queue_events 5
config event_queue: max_queue 8 log 3 order_events content_length

#Configure dynamic loaded libraries
dynamicpreprocessor directory /usr/local/lib/snort/dynamicpreprocessor/
dynamicengine /usr/local/lib/snort/dynamicengine/libsf_engine.so
dynamicdetection directory /usr/local/lib/snort/dynamicrules/

###################
                  #
# Flow and stream #
                  #
###################

preprocessor frag3_global: max_frags 8192
preprocessor frag3_engine: policy windows
preprocessor frag3_engine: policy linux
preprocessor frag3_engine: policy first
preprocessor frag3_engine: policy bsd detect_anomalies

preprocessor stream5_global: max_tcp 8192, track_tcp yes, \
track_udp yes, track_icmp yes
preprocessor stream5_tcp: bind_to any, policy windows
preprocessor stream5_tcp: bind_to any, policy linux
preprocessor stream5_tcp: bind_to any, policy vista
preprocessor stream5_tcp: bind_to any, policy macos
preprocessor stream5_tcp: policy BSD, ports both all, use_static_footprint_sizes
preprocessor stream5_udp
preprocessor stream5_icmp

##########################
                         #
# NEW                    #
# Performance Statistics #
                         #
##########################

#preprocessor perfmonitor: time 300 file /var/log/snort/snort.stats pktcnt 10000

#################
                #
# HTTP Inspect  #
                #
#################

preprocessor http_inspect: global iis_unicode_map unicode.map 1252

preprocessor http_inspect_server: server default \
                        ports  { 80 8080 3128 }  \
                        no_alerts \
                        non_strict \
                        non_rfc_char  { 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 }  \
                        flow_depth 0  \
                        apache_whitespace yes \
                        directory no \
                        iis_backslash no \
                        u_encode yes \
                        ascii yes \
                        chunk_length 500000 \
                        bare_byte yes \
                        double_decode yes \
                        iis_unicode yes \
                        iis_delimiter yes \
                        multi_slash no

##################
                 #
# Other preprocs #
                 #
##################

preprocessor rpc_decode: 111 32770 32771 32772 32773 32774 32775 32776 32777 32778 32779
preprocessor bo

#########################
                        #
# arpspoof preprocessor #
                        #
#########################
$arpspoof

#####################
                    #
# ftp preprocessor  #
                    #
#####################

preprocessor ftp_telnet: global \
inspection_type stateless

preprocessor ftp_telnet_protocol: telnet \
   normalize \
   ayt_attack_thresh 200

preprocessor ftp_telnet_protocol: \
    ftp server default \
    def_max_param_len 100 \
    ports { 21 } \
    ftp_cmds { USER PASS ACCT CWD SDUP SMNT QUIT REIN PORT PASV TYPE STRU MODE } \
    ftp_cmds { RETR STOR STOU APPE ALLO REST RNFR RNTO ABOR DELE RMD MKD PWD } \
    ftp_cmds { LIST NLST SITE SYST STAT HELP NOOP } \
    ftp_cmds { AUTH ADAT PROT PBSZ CONF ENC } \
    ftp_cmds { FEAT CEL CMD MACB } \
    ftp_cmds { MDTM REST SIZE MLST MLSD } \
    ftp_cmds { XPWD XCWD XCUP XMKD XRMD TEST CLNT } \
    alt_max_param_len 0 { CDUP QUIT REIN PASV STOU ABOR PWD SYST NOOP } \
    alt_max_param_len 100 { MDTM CEL XCWD SITE USER PASS REST DELE RMD SYST TEST STAT MACB EPSV CLNT LPRT } \
    alt_max_param_len 200 { XMKD NLST ALLO STOU APPE RETR STOR CMD RNFR HELP } \
    alt_max_param_len 256 { RNTO CWD } \
    alt_max_param_len 400 { PORT } \
    alt_max_param_len 512 { SIZE } \
    chk_str_fmt { USER PASS ACCT CWD SDUP SMNT PORT TYPE STRU MODE } \
    chk_str_fmt { RETR STOR STOU APPE ALLO REST RNFR RNTO DELE RMD MKD } \
    chk_str_fmt { LIST NLST SITE SYST STAT HELP } \
    chk_str_fmt { AUTH ADAT PROT PBSZ CONF ENC } \
    chk_str_fmt { FEAT CEL CMD } \
    chk_str_fmt { MDTM REST SIZE MLST MLSD } \
    chk_str_fmt { XPWD XCWD XCUP XMKD XRMD TEST CLNT } \
    cmd_validity MODE < char ASBCZ > \
    cmd_validity STRU < char FRP > \
    cmd_validity ALLO < int [ char R int ] > \
    cmd_validity TYPE < { char AE [ char NTC ] | char I | char L [ number ] } > \
    cmd_validity MDTM < [ date nnnnnnnnnnnnnn[.n[n[n]]] ] string > \
    cmd_validity PORT < host_port >

preprocessor ftp_telnet_protocol: ftp client default \
   max_resp_len 256 \
   bounce yes \
   telnet_cmds yes

#####################
                    #
# SMTP preprocessor #
                    #
#####################

preprocessor SMTP: \
    ports { 25 465 691 } \
    inspection_type stateful \
    normalize cmds \
    valid_cmds { MAIL RCPT HELP HELO ETRN EHLO EXPN VRFY ATRN SIZE BDAT DEBUG EMAL ESAM ESND ESOM EVFY IDENT NOOP RSET SEND SAML SOML AUTH TURN ETRN PIPELINING \
CHUNKING DATA DSN RSET QUIT ONEX QUEU STARTTLS TICK TIME TURNME VERB X-EXPS X-LINK2STATE XADR XAUTH XCIR XEXCH50 XGEN XLICENSE XQUEU XSTA XTRN XUSR } \
    normalize_cmds { MAIL RCPT HELP HELO ETRN EHLO EXPN VRFY ATRN SIZE BDAT DEBUG EMAL ESAM ESND ESOM EVFY IDENT NOOP RSET SEND SAML SOML AUTH TURN ETRN \
PIPELINING CHUNKING DATA DSN RSET QUIT ONEX QUEU STARTTLS TICK TIME TURNME VERB X-EXPS X-LINK2STATE XADR XAUTH XCIR XEXCH50 XGEN XLICENSE XQUEU XSTA XTRN XUSR } \
    max_header_line_len 1000 \ 
    max_response_line_len 512 \
    alt_max_command_line_len 260 { MAIL } \
    alt_max_command_line_len 300 { RCPT } \
    alt_max_command_line_len 500 { HELP HELO ETRN EHLO } \
    alt_max_command_line_len 255 { EXPN VRFY ATRN SIZE BDAT DEBUG EMAL ESAM ESND ESOM EVFY IDENT NOOP RSET } \
    alt_max_command_line_len 246 { SEND SAML SOML AUTH TURN ETRN PIPELINING CHUNKING DATA DSN RSET QUIT ONEX } \
    alt_max_command_line_len 246 { QUEU STARTTLS TICK TIME TURNME VERB X-EXPS X-LINK2STATE XADR } \
    alt_max_command_line_len 246 { XAUTH XCIR XEXCH50 XGEN XLICENSE XQUEU XSTA XTRN XUSR } \
    xlink2state { enable }

################
               #
# sf Portscan  #
               #
################

preprocessor sfportscan: scan_type { all } \
                         proto  { all } \
                         memcap { 10000000 } \
                         sense_level { medium } \
                         ignore_scanners { \$HOME_NET }

############################
                           #
# OLD                      #
# preprocessor dcerpc: \   #
#    autodetect \          #
#    max_frag_size 3000 \  #
#    memcap 100000         #
                           #
############################

###############
              #
# NEW         #
# DCE/RPC 2   #
              #
###############

preprocessor dcerpc2: memcap 102400, events [smb, co, cl]
preprocessor dcerpc2_server: default, policy WinXP, \
    detect [smb [139,445], tcp 135, udp 135, rpc-over-http-server 593], \
    autodetect [tcp 1025:, udp 1025:, rpc-over-http-server 1025:], \
    smb_max_chain 3

####################
                   #
# DNS preprocessor #
                   #
####################

preprocessor dns: \
    ports { 53 } \
    enable_rdata_overflow

##############################
                             #
# NEW                        #
# Ignore SSL and Encryption  #
                             #
##############################

preprocessor ssl: ports { 443 465 563 636 989 992 993 994 995 }, trustservers, noinspect_encrypted

#####################
                    #
# Snort Output Logs #
                    #
#####################

$snortalertlogtype_type
$alertsystemlog_type
$tcpdumplog_type
$snortmysqllog_info_chk
$snortunifiedlog_type
output log_null
						
#################
                #
# Misc Includes #
                #
#################

include /usr/local/etc/snort/reference.config
include /usr/local/etc/snort/classification.config
include /usr/local/etc/snort/threshold.conf

# Snort user pass through configuration
{$snort_config_pass_thru}

###################
                  #
# Rules Selection #
                  #
###################

{$selected_rules_sections}

EOD;

	return $snort_conf_text;
}

function snort_install_cron($should_install) {
    global $config, $g;
    $is_installed = false;
    if(!$config['cron']['item'])
        return;
    $x=0;
    foreach($config['cron']['item'] as $item) {
        if(strstr($item['command'], "snort_log_check.sh")) {
            $is_installed = true;
            break;
        }
        $x++;
    }
    switch($should_install) {
        case true:
            if(!$is_installed) {
                $cron_item = array();
                $cron_item['minute'] = "*/10";
                $cron_item['hour'] = "*";
                $cron_item['mday'] = "*";
                $cron_item['month'] = "*";
                $cron_item['wday'] = "*";
                $cron_item['who'] = "root";
                $cron_item['command'] = "/usr/bin/nice -n20 /usr/local/stairway/tools/snort_log_check.sh";      
                $config['cron']['item'][] = $cron_item;
                write_config("Snort Log Rotation");
                if(!$g['booting']) 
                    configure_cron();
            }
        break;
        case false:
            if($is_installed == true) {
                if($x > 0) {
                    unset($config['cron']['item'][$x]);
                    write_config();
                    if(!$g['booting'])
                        configure_cron();
                }
            }
        break;
    }
}

/*   check downloaded text from snort.org to make sure that an error did not occur
 *   for example, if you are not a premium subscriber you can only download rules
 *   so often, etc.
 */
function check_for_common_errors($filename) {
	global $snort_filename, $snort_filename_md5, $console_mode;
	ob_flush();
	$contents = file_get_contents($filename);
	if(stristr($contents, "You don't have permission")) {
		if(!$console_mode) {
			update_all_status("An error occured while downloading {$filename}.");
			hide_progress_bar_status();
		} else {
			log_error("An error occured.  Scroll down to inspect it's contents.");
			echo "An error occured.  Scroll down to inspect it's contents.";
		}
		if(!$console_mode) {
			update_output_window(strip_tags("$contents"));
		} else {
			$contents = strip_tags($contents);
			log_error("Error downloading snort rules: {$contents}");
			echo "Error downloading snort rules: {$contents}";
		}
		scroll_down_to_bottom_of_page();
		exit;
	}
}

/* force browser to scroll all the way down */
function scroll_down_to_bottom_of_page() {
	global $snort_filename, $console_mode;
	ob_flush();
	if(!$console_mode)
		echo "\n<script type=\"text/javascript\">parent.scrollTo(0,1500);\n</script>";
}

/* ensure downloaded file looks sane */
function verify_downloaded_file($filename) {
	global $snort_filename, $snort_filename_md5, $console_mode;
	ob_flush();
	if(filesize($filename)<9500) {
		if(!$console_mode) {
			update_all_status("Checking {$filename}...");
			check_for_common_errors($filename);
		}
	}
	update_all_status("Verifying {$filename}...");
	if(!file_exists($filename)) {
		if(!$console_mode) {
			update_all_status("Could not fetch snort rules ({$filename}).  Check oinkid key and dns and try again.");
			hide_progress_bar_status();
		} else {
			log_error("Could not fetch snort rules ({$filename}).  Check oinkid key and dns and try again.");
			echo "Could not fetch snort rules ({$filename}).  Check oinkid key and dns and try again.";
		}
		exit;
	}
	update_all_status("Verifyied {$filename}.");
}

/* extract rules */
function extract_snort_rules_md5($tmpfname) {
	global $snort_filename, $snort_filename_md5, $console_mode;
	ob_flush();
	if(!$console_mode) {
		$static_output = gettext("Extracting snort rules...");
		update_all_status($static_output);
	}
	if(!is_dir("/usr/local/etc/snort/rules/"))
		mkdir("/usr/local/etc/snort/rules/");
	$cmd = "/usr/bin/tar xzf {$tmpfname}/{$snort_filename} -C /usr/local/etc/snort/ rules/";
	$handle = popen("{$cmd} 2>&1", 'r');
	while(!feof($handle)) {
		$buffer = fgets($handle);
		update_output_window($buffer);
	}
	pclose($handle);	

	if(!$console_mode) {
		$static_output = gettext("Snort rules extracted.");
		update_all_status($static_output);
	} else {
		log_error("Snort rules extracted.");
		echo "Snort rules extracted.";
	}
}

/* verify MD5 against downloaded item */
function verify_snort_rules_md5($tmpfname) {
	global $snort_filename, $snort_filename_md5, $console_mode;
	ob_flush();
	if(!$console_mode) {
		$static_output = gettext("Verifying md5 signature...");
		update_all_status($static_output);
	}

        $md555 = file_get_contents("{$tmpfname}/{$snort_filename_md5}");
        $md5 = `/bin/echo "{$md555}" | /usr/bin/awk '{ print $4 }'`;
	$file_md5_ondisk = `/sbin/md5 {$tmpfname}/{$snort_filename} | /usr/bin/awk '{ print $4 }'`;
	if($md5 == $file_md5_ondisk) {
		if(!$console_mode) {
			$static_output = gettext("snort rules: md5 signature of rules mismatch.");
			update_all_status($static_output);
			hide_progress_bar_status();
		} else {
			log_error("snort rules: md5 signature of rules mismatch.");
			echo "snort rules: md5 signature of rules mismatch.";
		}
		exit;
	}
}

/* hide progress bar */
function hide_progress_bar_status() {
	global $snort_filename, $snort_filename_md5, $console_mode;
	ob_flush();
	if(!$console_mode)
		echo "\n<script type=\"text/javascript\">document.progressbar.style.visibility='hidden';\n</script>";
}

/* unhide progress bar */
function unhide_progress_bar_status() {
        global $snort_filename, $snort_filename_md5, $console_mode;
        ob_flush();
        if(!$console_mode)
                echo "\n<script type=\"text/javascript\">document.progressbar.style.visibility='visible';\n</script>";
}

/* update both top and bottom text box during an operation */
function update_all_status($status) {
	global $snort_filename, $snort_filename_md5, $console_mode;
	ob_flush();
	if(!$console_mode) {
		update_status($status);
		update_output_window($status);
	}
}

/* obtain alert description for an ip address */
function get_snort_alert($ip) {
	global $snort_alert_file_split, $snort_config;
	if(!file_exists("/var/log/snort/alert"))
		return;
	if(!$snort_config)
		$snort_config = read_snort_config_cache();
	if($snort_config[$ip])
		return $snort_config[$ip];
	if(!$snort_alert_file_split)
		$snort_alert_file_split = split("\n", file_get_contents("/var/log/snort/alert"));
	foreach($snort_alert_file_split as $fileline) {
		if (preg_match("/\[\*\*\] (\[.*\]) (.*) (\[\*\*\])/", $fileline, $matches))
			$alert_title = $matches[2];
		if (preg_match("/(\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b)/", $fileline, $matches))
			$alert_ip = $matches[0];
		if($alert_ip == $ip) {
			if(!$snort_config[$ip])
				$snort_config[$ip] = $alert_title;
			return $alert_title;
		}
	}
	return "n/a";
}

function make_clickable($buffer) {
    global $config, $g;
    /* if clickable urls is disabled, simply return buffer back to caller */
    $clickablalerteurls = $config['installedpackages']['snort']['config'][0]['oinkmastercode'];
    if(!$clickablalerteurls)
    	return $buffer;
    $buffer = eregi_replace("(^|[ \n\r\t])((http(s?)://)(www\.)?([a-z0-9_-]+(\.[a-z0-9_-]+)+)(/[^/ \n\r]*)*)","\\1<a href=\"\\2\" target=\"_blank\">\\2</a>", $buffer);
    $buffer = eregi_replace("(^|[ \n\r\t])((ftp://)(www\.)?([a-z0-9_-]+(\.[a-z0-9_-]+)+)(/[^/ \n\r]*)*)","\\1<a href=\"\\2\" target=\"_blank\">\\2</a>", $buffer);
    $buffer = eregi_replace("([a-z_-][a-z0-9\._-]*@[a-z0-9_-]+(\.[a-z0-9_-]+)+)","<a href=\"mailto:\\1\">\\1</a>", $buffer);
    $buffer = eregi_replace("(^|[ \n\r\t])(www\.([a-z0-9_-]+(\.[a-z0-9_-]+)+)(/[^/ \n\r]*)*)","\\1<a href=\"http://\\2\" target=\"_blank\">\\2</a>", $buffer);
    $buffer = eregi_replace("(^|[ \n\r\t])(ftp\.([a-z0-9_-]+(\.[a-z0-9_-]+)+)(/[^/ \n\r]*)*)","\\1<a href=\"ftp://\\2\" target=\"_blank\">\\2</a>", $buffer);

    return $buffer;
}

function read_snort_config_cache() {
	global $g, $config, $snort_config;
	if($snort_config)
		return $snort_config;
	if(file_exists($g['tmp_path'] . '/snort_config.cache')) {
		$snort_config = unserialize(file_get_contents($g['tmp_path'] . '/snort_config.cache'));
		return $snort_config;
	}
	return;
}

function write_snort_config_cache($snort_config) {
	global $g, $config;
	conf_mount_rw();
	$configcache = fopen($g['tmp_path'] . '/snort_config.cache', "w");
	if(!$configcache) {
		log_error("Could not open {$g['tmp_path']}/snort_config.cache  for writing.");
		return false;
	}
	fwrite($configcache, serialize($snort_config));
	fclose($configcache);
	conf_mount_ro();
	return true;
}

function snort_advanced() {
	global $g, $config;
	sync_package_snort();
}

function snort_define_servers() {
	global $g, $config;
	sync_package_snort();
}

?>
